<?php

namespace origin;

use origin\App;
use think\Db;

/**
 * 返利类
 * @author dece <decezz@qq.com>
 * 1.必须使用rebate表和rebate_back表  必须使用origin框架
 * 2.金额关系表记录了用户的金额、冻结金额、费率和上级用户
 * 3.返利功能无限级向上返利
 * 4.如果多个用户表都需要返利，请开启分组功能，表名为分组名
 * 5.开启奖励冻结，返回的奖励将在冻结金额中
 * 6.中途用户返利失败，后续用户返利也将终止
 */
class Rebate
{
    /**
     * 配置信息
     * @field   on_group    是否开启分组功能
     * @field   on_ice      是否开启奖励冻结
     */
    protected static $conf = [
        'on_group'  => false,
        'on_ice'    => false,
    ];
    /**
     * 执行返利
     * @param int       $uid    关联ID
     * @param float     $price  金额
     * @param int       $oid    订单ID
     * @param string    $group  分组 (no)
     */
    public static function rebate( $order = ['uid'=>0, 'price'=>0, 'oid'=>0] , $data = ['group'=>''] )
    {
        // 条件
        $where = [
            'uid' => $order['uid'],
        ];
        // 启用分组
        if (self::$conf['on_group']) {
            $where['group'] = $data['group'];
        }
        // 防止死循环
        if (!array_key_exists('while', $data) || !is_numeric($data['while'])) {
            $data['while'] = 10;
        }
        // 循环次数限制
        if ($data['while'] <= 0) {
            return App::error('循环次数达到上限');
        } else {
            $data['while'] = $data['while'] - 1;
        }
        // 金额关系
        $row = Db::name('rebate')->where($where)->find();

        if (!$row) {
            return App::error('用户不存在');
        }
        // 计算奖励
        $gold = bcmul($order['price'], $row['rate'], 2);
        // 是否开启奖励冻结
        if (self::$conf['on_ice']) {
            $ice_gold = $gold;
            $on_ice = 1;
        } else {
            $ice_gold = 0;
            $on_ice = 0;
        }
        // 记录返利
        $back_id = Db::name('rebate_back')->insertGetId([
            'oid'           => $order['oid'],
            'uid'           => $order['uid'],
            'pid'           => $row['pid'],
            'group'         => $data['group'],
            'price'         => $order['price'],
            'gold'          => $gold,
            'ice_gold'      => $ice_gold,
            'rate'          => $row['rate'],
            'on_ice'        => $on_ice,
            'is_back'       => 0,
            'createtime'    => time(),
            'updatetime'    => time(),
        ]);
        // 启动事务
        Db::startTrans();
        try {
            // 为用户返利
            $back_res = Db::name('rebate')->where($where)->update([
                'gold'          => bcadd($row['gold'], $gold, 2),
                'ice_gold'      => bcadd($row['ice_gold'], $ice_gold, 2),
                'updatetime'    => time(),
            ]);
            if (!$back_res) {
                // 回滚事务
                Db::rollback();
            }
            // 修改返利状态
            $save_back = Db::name('rebate_back')->where('id', $back_id)->update(['is_back'=>1]);
            if (!$save_back) {
                // 回滚事务
                Db::rollback();
            }
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            // 异常退出
            return App::error($e);
        }
        // 父级存在
        if (!empty($row['pid'])) {
            // 重新赋值
            $order['uid'] = $row['pid'];
            // 父级返利
            $reb_res = self::rebate($order, $data);
        }
        return App::success('用户'.$where['uid'].'返利完成');
    }
}